<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Promise</title>
</head>

<body>

</body>
<script>
  class MyPromise {

    constructor(executor) {
      this.initBind()
      this.initValue()
      executor(this.resolve, this.reject)
    }

    initBind() {
      this.resolve = this.resolve.bind(this)
      this.reject = this.reject.bind(this)

    }

    initValue() {
      this.PromiseResult = null
      this.PromiseState = 'pending'
      // 保存回调 数组-->多次then
      this.onFulfilledCallbacks = []
      this.onRejectedCallbacks = []
    }

    resolve(value) {
      if (this.PromiseState !== 'pending') return
      this.PromiseResult = value
      this.PromiseState = 'fulfilled'
      // 执行回调
      while (this.onFulfilledCallbacks.length) {
        this.onFulfilledCallbacks.shift()(this.PromiseResult)
      }
    }

    reject(reason) {
      if (this.PromiseState !== 'pending') return
      this.PromiseResult = reason
      this.PromiseState = 'rejected'
      // 执行回调
      while (this.onRejectedCallbacks.length) {
        this.onRejectedCallbacks.shift()(this.PromiseResult)
      }
    }
    // then 入参为两个 回调函数
    then(onFulfilled, onRejected) {
      // 是否是函数
      onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val
      onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }

      var thenPromise = new MyPromise((resolve, reject) => {

        const resolvePromise = (cb) => {
          try {
            const x = cb(this.PromiseResult)
            if (x === thenPromise) {
              throw new Error('不能返回自身。。。')
            }
            if (x instanceof MyPromise) {
              x.then(resolve, reject)
            } else {
              resolve(x)
            }
          } catch (error) {
            reject(err)
            throw new Error(err)
          }
        }

        // 给回调传参
        if (this.PromiseState === 'fulfilled') {
          resolvePromise(this.PromiseResult)
        } else if (this.PromiseState === 'rejected') {
          resolvePromise(this.PromiseResult)
        } else if (this.PromiseState === 'pending') {
          // 如果状态为待定状态，暂时保存两个回调
          this.onFulfilledCallbacks.push(resolvePromise.bind(this, onFulfilled))
          this.onRejectedCallbacks.push(resolvePromise.bind(this, onRejected))
        }
      })
      return thenPromise
    }
  }


  Promise.all = function(promiseArr) {
    let res = []
    let len = 0
    return new Promise((resolve, reject)=>{
      promiseArr.forEach((item, index)=>{
        item.then(res => {
          res[index] = res
          len++
          if(len==promiseArr.length) resolve()
        }, 
        err => {
          reject(err)
        })
      })
    })
  }

  Promise.race = function(promiseArr){
    return new Promise((resolve, reject) => {
      promiseArr.forEach(item => {
        item.then(res => resolve(), err => reject())
      })
    })
  }





</script>
<style>

</style>

</html>

